package com.tomato.service;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.tomato.dto.RecordQueryDTO;
import com.tomato.dto.TodoRecordDTO;
import com.tomato.dto.TodoRecordSyncDTO;
import com.tomato.entity.TodoRecord;
import com.tomato.entity.TodoSetting;
import com.tomato.mapper.BatchMapper;
import com.tomato.mapper.TodoRecordMapper;
import com.tomato.mapper.TodoSettingMapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.util.List;
import java.util.stream.Collectors;

@Slf4j
@Service
public class TodoRecordServiceImpl implements TodoRecordService {
    private final TodoRecordMapper todoRecordMapper;
    private final TodoSettingMapper todoSettingMapper;
    private final BatchMapper batchMapper;

    public TodoRecordServiceImpl(TodoRecordMapper todoRecordMapper,
                                 TodoSettingMapper todoSettingMapper,
                                 BatchMapper batchMapper) {
        this.todoRecordMapper = todoRecordMapper;
        this.todoSettingMapper = todoSettingMapper;
        this.batchMapper = batchMapper;
    }

    @Override
    public TodoRecord createRecord(Long userId, TodoRecordDTO recordDTO) {
        log.debug("Creating new todo record for user: {}", userId);
        // 验证设定属于该用户
        TodoSetting setting = todoSettingMapper.selectById(recordDTO.getSettingId());
        if (setting == null || !setting.getUserId().equals(userId)) {
            log.warn("Invalid setting ID for record creation: {}", recordDTO.getSettingId());
            throw new RuntimeException("无效的待办设定");
        }

        TodoRecord record = new TodoRecord();
        BeanUtils.copyProperties(recordDTO, record);
        record.setCreatedAt(LocalDateTime.now());

        todoRecordMapper.insert(record);
        log.info("New todo record created: {}", record.getId());
        return record;
    }

    @Transactional
    @Override
    public void uploadRecords(Long userId, List<TodoRecordSyncDTO> syncDTOs) {
        if (syncDTOs.isEmpty()) {
            log.debug("用户 {} 上传记录列表为空", userId);
            return;
        }

        log.debug("用户 {} 开始上传 {} 条记录", userId, syncDTOs.size());

        List<TodoRecord> records = syncDTOs.stream()
                .map(dto -> dto.toEntity(userId))
                .collect(Collectors.toList());

        // 过滤掉已存在的记录，防止重复插入
        List<TodoRecord> uniqueRecords = records.stream()
                .filter(record -> {
                    boolean exists = isRecordExists(record);
                    if (exists) {
                        log.debug("用户 {} 的记录已存在，开始时间: {}, 结束时间: {}, 创建时间: {}",
                                record.getUserId(), record.getStartTime(), record.getEndTime(), record.getCreatedAt());
                    }
                    return !exists;
                })
                .collect(Collectors.toList());

        if (!uniqueRecords.isEmpty()) {
            batchMapper.batchInsertRecords(uniqueRecords);
            log.info("用户 {} 新增 {} 条记录，过滤重复记录 {} 条",
                    userId, uniqueRecords.size(), records.size() - uniqueRecords.size());
        } else {
            log.info("用户 {} 上传的 {} 条记录均为重复记录，已全部过滤", userId, records.size());
        }
    }

    @Override
    public List<TodoRecord> queryRecords(Long userId, RecordQueryDTO queryDTO) {
        log.debug("Querying todo records for user: {} between {} and {}",
                userId, queryDTO.getStartDate(), queryDTO.getEndDate());

        LocalDateTime start = queryDTO.getStartDate().atStartOfDay();
        LocalDateTime end = queryDTO.getEndDate().plusDays(1).atStartOfDay();

        return todoRecordMapper.selectByUserIdAndDateRange(userId, start, end);
    }

    /**
     * 检查记录是否已存在
     *
     * @param record 待检查的记录
     * @return 是否已存在
     */
    private boolean isRecordExists(TodoRecord record) {
        log.debug("检查记录是否存在: 用户ID={}, 开始时间={}, 结束时间={}, 创建时间={}",
                record.getUserId(), record.getStartTime(), record.getEndTime(), record.getCreatedAt());

        // 根据用户ID、开始时间和结束时间判断记录是否已存在（允许±1毫秒的时间误差）
        QueryWrapper<TodoRecord> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("user_id", record.getUserId())
                .ge("start_time", record.getStartTime().minusNanos(1000*1000000))  // 允许前后1秒的差异
                .le("start_time", record.getStartTime().plusNanos(1000*1000000))
                .ge("end_time", record.getEndTime().minusNanos(1000*1000000))
                .le("end_time", record.getEndTime().plusNanos(1000*1000000));

        int count = Math.toIntExact(todoRecordMapper.selectCount(queryWrapper));
        log.debug("近似匹配查询结果数量: {}", count);

        return count > 0;
    }
}